package biz

import (
	"context"
	"time"
)

// User 用户数据模型
type User struct {
	ID           uint32    `gorm:"primaryKey;autoIncrement"`
	Username     string    `gorm:"unique;not null;comment:'用户名'"`
	Password     string    `gorm:"not null;comment:'密码'"`
	PhoneNumber  string    `gorm:"comment:'手机号'"`
	Email        string    `gorm:"comment:'用户邮箱'"`
	UserStatus   bool      `gorm:"not null;default:true;comment:'是否启用[0:否，1:是]'"`
	Gender       *uint8    `gorm:"comment:'性别[1:男，2:女，0:保密]'"`
	OpenID       string    `gorm:"comment:'openId'"`
	Avatar       string    `gorm:"comment:'头像'"`
	Admire       string    `gorm:"comment:'赞赏'"`
	Subscribe    string    `gorm:"type:text;comment:'订阅'"`
	Introduction string    `gorm:"type:longtext;comment:'简介'"`
	UserType     uint8     `gorm:"not null;default:2;comment:'用户类型[0:admin，1:管理员，2:普通用户]'"`
	CreateTime   time.Time `gorm:"comment:'创建时间';autoCreateTime"`
	UpdateTime   time.Time `gorm:"comment:'最终修改时间';autoUpdateTime"`
	UpdateBy     *string   `gorm:"comment:'最终修改人'"`
	Deleted      bool      `gorm:"not null;default:false;comment:'是否启用[0:未删除，1:已删除]'"`
}

func (User) TableName() string {
	return "user"
}

// UserRepo 定义了一个用户数据仓库接口，它将“用户数据模型”在数据库上的基础操作封装为一系列方法。
type UserRepo interface {
	// CreateUser 创建用户
	// 参数 model 为 User结构体实例，表示要创建的用户数据模型
	// 返回值：
	//   uint: 创建成功的用户ID
	//   error: 在创建过程中发生的任何错误（nil表示无错误）
	Regist(ctx context.Context, model *User) (*User, error)

	// LoginUser 用户登录
	// 参数 model 为 User结构体实例，包含用于验证登录的用户名、密码等信息
	// 返回值：
	//   uint: 登录成功的用户ID
	//   error: 在登录验证过程中发生的任何错误（nil表示无错误）
	LoginUser(ctx context.Context, model *User) (uint, error)

	// GetUserByID 根据用户ID获取用户信息
	// 参数 id 为待查询用户的ID
	// 返回值：
	//   *User: 查询到的用户信息，若未找到则返回nil
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserByID(ctx context.Context, id uint) (*User, error)

	// GetUserByUsername 根据用户名获取用户信息
	// 参数 username 为待查询用户的用户名
	// 返回值：
	//   *User: 查询到的用户信息，若未找到则返回nil
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserByUsername(ctx context.Context, username string) (*User, error)

	// GetUserByOpenID 根据OpenID获取用户信息
	// 参数 openID 为待查询用户的OpenID
	// 返回值：
	//   *User: 查询到的用户信息，若未找到则返回nil
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserByOpenID(ctx context.Context, openID string) (*User, error)

	// UpdateUser 更新用户信息
	// 参数 model 为User结构体实例，包含待更新的用户数据
	// 返回值：
	//   error: 在更新过程中发生的任何错误（nil表示无错误）
	UpdateUser(ctx context.Context, model *User) error

	// DeleteUser 删除指定ID的用户
	// 参数 id 为待删除用户的ID
	// 返回值：
	//   error: 在删除过程中发生的任何错误（nil表示无错误）
	DeleteUser(ctx context.Context, id uint) error

	// GetUserList 获取用户列表，支持分页
	// 参数 page, pageSize 分别为当前页数和每页大小
	// 返回值：
	//   []*User: 当前页的用户信息列表
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserList(ctx context.Context, page, pageSize int) ([]*User, error)

	// GetUserCount 获取用户总数
	// 返回值：
	//   int64: 数据库中用户总数
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserCount(ctx context.Context) (int64, error)

	// GetUserByPhoneNumber 根据手机号获取用户信息
	// 参数 phoneNumber 为待查询用户的手机号
	// 返回值：
	//   *User: 查询到的用户信息，若未找到则返回nil
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*User, error)

	// GetUserByEmail 根据邮箱获取用户信息
	// 参数 email 为待查询用户的邮箱
	// 返回值：
	//   *User: 查询到的用户信息，若未找到则返回nil
	//   error: 在查询过程中发生的任何错误（nil表示无错误）
	GetUserByEmail(ctx context.Context, email string) (*User, error)

	// GetUserByUsernameAndPassword 根据用户名和密码验证并获取用户信息
	// 参数 username, password 分别为待验证的用户名和密码
	// 返回值：
	//   *User: 验证成功的用户信息，若验证失败或未找到用户则返回nil
	//   error: 在验证过程中发生的任何错误（nil表示无错误）
	GetUserByUsernameAndPassword(ctx context.Context, username, password string) (*User, error)

	// GetUserByPhoneNumberAndPassword 根据手机号和密码验证并获取用户信息
	// 参数 phoneNumber, password 分别为待验证的手机号和密码
	// 返回值：
	//   *User: 验证成功的用户信息，若验证失败或未找到用户则返回nil
	//   error: 在验证过程中发生的任何错误（nil表示无错误）
	GetUserByPhoneNumberAndPassword(ctx context.Context, phoneNumber, password string) (*User, error)

	// GetUserByEmailAndPassword 根据邮箱和密码验证并获取用户信息
	// 参数 email, password 分别为待验证的邮箱和密码
	// 返回值：
	//   *User: 验证成功的用户信息，若验证失败或未找到用户则返回nil
	//   error: 在验证过程中发生的任何错误（nil表示无错误）
	GetUserByEmailAndPassword(ctx context.Context, email, password string) (*User, error)

	// GetUserByOpenIDAndPassword 根据OpenID和密码验证并获取用户信息
	// 参数 openID, password 分别为待验证的OpenID和密码
	// 返回值：
	//   *User: 验证成功的用户信息，若验证失败或未找到用户则返回nil
	//   error: 在验证过程中发生的任何错误（nil表示无错误）
	//GetUserByOpenIDAndPassword(ctx context.Context, openID, password string) (*User, error)

}

// Implementing UserRepo methods for UserUseCase:

func (uc *UserUseCase) Regist(ctx context.Context, model *User) (*User, error) {
	return uc.repo.Regist(ctx, model)
}

func (uc *UserUseCase) LoginUser(ctx context.Context, model *User) (uint, error) {
	return uc.repo.LoginUser(ctx, model)
}

func (uc *UserUseCase) GetUserByID(ctx context.Context, id uint) (*User, error) {
	return uc.repo.GetUserByID(ctx, id)
}

func (uc *UserUseCase) GetUserByUsername(ctx context.Context, username string) (*User, error) {
	return uc.repo.GetUserByUsername(ctx, username)
}

func (uc *UserUseCase) GetUserByOpenID(ctx context.Context, openID string) (*User, error) {
	return uc.repo.GetUserByOpenID(ctx, openID)
}

func (uc *UserUseCase) UpdateUser(ctx context.Context, model *User) error {
	return uc.repo.UpdateUser(ctx, model)
}

func (uc *UserUseCase) DeleteUser(ctx context.Context, id uint) error {
	return uc.repo.DeleteUser(ctx, id)
}

func (uc *UserUseCase) GetUserList(ctx context.Context, page, pageSize int) ([]*User, error) {
	return uc.repo.GetUserList(ctx, page, pageSize)
}

func (uc *UserUseCase) GetUserCount(ctx context.Context) (int64, error) {
	return uc.repo.GetUserCount(ctx)
}

func (uc *UserUseCase) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*User, error) {
	return uc.repo.GetUserByPhoneNumber(ctx, phoneNumber)
}

func (uc *UserUseCase) GetUserByEmail(ctx context.Context, email string) (*User, error) {
	return uc.repo.GetUserByEmail(ctx, email)
}

func (uc *UserUseCase) GetUserByUsernameAndPassword(ctx context.Context, username, password string) (*User, error) {
	return uc.repo.GetUserByUsernameAndPassword(ctx, username, password)
}

func (uc *UserUseCase) GetUserByPhoneNumberAndPassword(ctx context.Context, phoneNumber, password string) (*User, error) {
	return uc.repo.GetUserByPhoneNumberAndPassword(ctx, phoneNumber, password)
}

func (uc *UserUseCase) GetUserByEmailAndPassword(ctx context.Context, email, password string) (*User, error) {
	return uc.repo.GetUserByEmailAndPassword(ctx, email, password)
}

//func (uc *UserUseCase) GetUserByOpenIDAndPassword(ctx context.Context, openID, password string) (*User, error) {
//	return uc.repo.GetUserByOpenIDAndPassword(ctx, openID, password)
//}
